/**
 * 
 * @author Travis C lynch <travisclynch@student.midlandstech.edu>
 * @version Apr 17 2012
 * <p>
 * <b>Instructions:</b><br>
 * Write a class definition for a TNode<T> class to represent a generalized tree with the following methods (implementing TNodeInterface). A main method is provided to test your class, although it should run correctly with any main method. The class should contain a constructor with one T parameter so that the new node contains the parameter as data.
 * <ul>
 * <li>A data field of type T
 * <li>Three TNode<T> fields for the first, last and next children.
 * <li>An int field for the number of children.
 * <li>A method with the following signature to return a String representing the subtree with a root at the parameter. For ptr and each of its siblings, concatenate the data, then, if there are any children,recursively concatenate the children, enclosed in parentheses:
 * </ul>
 * <p>
 * <b>Description:</b><br>
 * 
 */
public class TNode<T> implements TNodeInterface<T> {
	/**
	 * Data of Generic type T
	 */
	private T data;
	/**
	 * Varable of type TNode for self refrence
	 */
	private TNode<T> first, last, sibling;
	/**
	 * Constructor for the TNode class
	 * @param newData Data to be imputed at the time of creation
	 */
	public TNode(T newData) {	data=newData;	};
	/**
	 * @return Returns the data in the node
	 */
	@Override
	public T getData() {	return data;	}
	/**
	 * @param d Data type T for the node
	 */
	public void setData(T d) { data=d; }
	/**
	 * @return Returns the first sibling for the individual node. If null then there are no siblings
	 */
	public TNode<T> getFirst(){
		return first;
	}
	/**
	 * @param newData Adds a new node as a sibling to the current node with data of generic type T
	 */
	@Override 
	public void addChild(T newData) {
		if(first==null){
			first=new TNode<T>(newData);
			last=first;
		}
		if(first!=null){
			last.sibling=new TNode<T>(newData);
			last=last.sibling;
		}
	}
	/**
	 * @return Returns the reference of the first siblings of the node. If no siblings then returns null
	 */
	@Override
	public TNode<T> getFirstChild() {
		return first;
	}
	/**
	 * @return Returns the reference of the next linked sibling in the link list of the nodes. If no next siblings then returns null
	 */
	@Override
	public TNode<T> getNext() {
		return sibling;
	}
	/**
	 * @return Returns the a String the outlines both the data and the structure of the data with parentesis. 
	 */
	public String toString(){
		TNode<T> point=first;
		String message="";
		message=data + " ";
		if(first!=null) {
			message+=" (" + point.toString();
			point=point.sibling.sibling;
			while (point!=null){
				message+=point.toString();
				point=point.sibling;
			}
			message+=") ";
			
		}
		return message;
	}

	public static void main(String[] args) {
		TNode<String> root = new TNode<String>("Root");
		TNode<String> ptr = root;
		ptr.addChild("A1");//child of root
		ptr.addChild("A2");//child of root
		ptr.addChild("A3");//child of root
		ptr.addChild("A4");//child of root
		ptr=ptr.getFirstChild();
		ptr.addChild("B1");//child of A1
		ptr.addChild("B2");//child of A1
		ptr.addChild("B3");//child of A1
		ptr=ptr.getNext();
		ptr.addChild("C1");//child of A2
		ptr.addChild("C2");//child of A2
		ptr=ptr.getNext();
		ptr.addChild("D1");//child of A3
		ptr.addChild("D2");//child of A3
		ptr.addChild("D3");//child of A3
		ptr.addChild("D4");//child of A3
		ptr = root.getFirstChild().getFirstChild();
		ptr.addChild("E1");//child of B1
		ptr.addChild("E2");//child of B1
		ptr.addChild("E3");//child of B1
		ptr=ptr.getNext();
		ptr.addChild("F1");//child of B2
		ptr.addChild("F2");//child of B2
		ptr.addChild("F3");//child of B2
		System.out.println(root);
	}
}
